/**
 *
 */
package cn.hg.jfsa.manage.interceptor;

import cn.hg.base.jfinal.controller.BaseController;
import cn.hg.base.kit.RequestKit;
import cn.hg.jfsa.common.JfsaConstants;
import cn.hg.jfsa.common.LogManager;
import cn.hg.jfsa.core.SessionThreadLocal;
import cn.hg.jfsa.model.JfsaAdmin;
import cn.hg.jfsa.model.JfsaLogAction;
import cn.hg.jfsa.model.JfsaResource;
import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.Enumeration;
import java.util.Map;

/**
 * @author golly
 *
 */
public class AuthInterceptor implements Interceptor {
	private static int maxOutputLengthOfParaValue = 1020;

	/*
	 * (non-Javadoc)
	 *
	 * @see com.jfinal.aop.Interceptor#intercept(com.jfinal.aop.Invocation)
	 */
	@Override
	public void intercept(Invocation inv) {
		JfsaAdmin admin = SessionThreadLocal.getAdmin();
		inv.getController().setAttr(JfsaConstants.CURRENT_ADMIN, admin);

		Map<String, JfsaResource> actionMap = SessionThreadLocal.getAdminAuthAction();
		JfsaResource resource = actionMap.get(inv.getActionKey());
		Date now = new Date();

		if (null != admin && admin.getId() == 1) { // ID为1的超级用户具有所有权限
			// 设置当前登录的admin实例到页面
			inv.invoke();

			// 处理操作日志
			this.getLog(admin, inv, resource, now);
		} else {
			if (null != actionMap && actionMap.containsKey(inv.getActionKey())) {
				inv.invoke();

				// 处理操作日志
				this.getLog(admin, inv, resource, now);
			} else {
				if (inv.getController() instanceof BaseController) {
					BaseController c = (BaseController) inv.getController();
					if (c.isAjaxRequest()) { // 如果是Ajax请求
						c.renderAjaxFailed("-1", "您没有此操作的权限，请联系管理员！");
					} else {
						c.render("/manage/no_right.html");
					}
				}
			}
		}

	}

	private void getLog(JfsaAdmin admin, Invocation inv, JfsaResource resource, Date accessTime) {
		// 操作是否允许记录日志
		if(resource == null || !resource.getIsLog()) return;
		// 日志是否打开
		if (!LogManager.me().isLogEnabled()) return;

		JfsaLogAction log = new JfsaLogAction()
				.setAdminId(admin.getId())
				.setClientIp(RequestKit.getIpAddress(inv.getController().getRequest()))
				.setServerIp(inv.getController().getRequest().getLocalAddr())
				.setActionName(resource == null ? null : resource.getName())
				.setUri(inv.getActionKey())
				.setActionTime(accessTime)
				.setExecutionTime((int) (new Date().getTime() - accessTime.getTime()))
				.setQueryString(inv.getController().getRequest().getQueryString())
				.setParams(this.getParaString(inv.getController().getRequest()))
				.setSessionId(inv.getController().getCookie("JSESSIONID"))
				.setCookieId(inv.getController().getCookieObjects().toString())
				.setRefer(RequestKit.getReferer(inv.getController().getRequest()))
				;

		LogManager.me().add(log);
	}

	private String getParaString(HttpServletRequest request){
		StringBuilder sb = new StringBuilder();

		// print all parameters
		Enumeration<String> e = request.getParameterNames();
		if (e.hasMoreElements()) {
			while (e.hasMoreElements()) {
				String name = e.nextElement();
				String[] values = request.getParameterValues(name);
				if (values.length == 1) {
					sb.append(name).append("=");
					if (values[0] != null && values[0].length() > maxOutputLengthOfParaValue) {
						sb.append(values[0].substring(0, maxOutputLengthOfParaValue)).append("...");
					} else {
						sb.append(values[0]);
					}
				}
				else {
					sb.append(name).append("[]={");
					for (int i=0; i<values.length; i++) {
						if (i > 0)
							sb.append(",");
						sb.append(values[i]);
					}
					sb.append("}");
				}
				sb.append("  ");
			}
		}

		return sb.toString();
	}
}
